/**
 * @desc 表单验证
 * @param type 表单类型
 * @param data 表单数据
 * @param message 错误信息
 * @param rule 验证规则
 */
function check(type: string, data: any, message?: string, rule?: Function) {
    /**
     * 报错
     * @param judge 判断条件
     */
    function error(judge: Boolean) {
        if (judge) {
            return judge
        } else {
            throw new Error(message)
        }
    }

    /**
     * 判空
     */
    function emptyCheck() {
        if (typeof data === 'object') {
            if (Array.isArray(data)) {
                return data.length > 0
            } else {
                return Object.keys(data).length > 0
            }
        } else if (typeof data === 'string') {
            // 如果是字符串，先去空格
            data = data.trim()
            return data !== ''
        } else if (typeof data === 'undefined') {
            return false
        } else if (data === null) {
            return false
        }
    }

    /**
     * 身份证号码验证
     */
    function checkIdCard() {
        const city = {
            11: '北京',
            12: '天津',
            13: '河北',
            14: '山西',
            15: '内蒙古',
            21: '辽宁',
            22: '吉林',
            23: '黑龙江 ',
            31: '上海',
            32: '江苏',
            33: '浙江',
            34: '安徽',
            35: '福建',
            36: '江西',
            37: '山东',
            41: '河南',
            42: '湖北 ',
            43: '湖南',
            44: '广东',
            45: '广西',
            46: '海南',
            50: '重庆',
            51: '四川',
            52: '贵州',
            53: '云南',
            54: '西藏 ',
            61: '陕西',
            62: '甘肃',
            63: '青海',
            64: '宁夏',
            65: '新疆',
            71: '台湾',
            81: '香港',
            82: '澳门',
            91: '国外 ',
        }
        let tip = ''
        let pass = true
        // 验证身份证格式（6个地区编码，8位出生日期，3位顺序号，1位校验位）
        if (data == '') {
            pass = false
        } else if (!data || !/^\d{6}(18|19|20)?\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/i.test(data)) {
            tip = '身份证号格式错误'
            pass = false
        } else if (!city[data.substr(0, 2)]) {
            tip = '身份证号格式错误'
            pass = false
        } else {
            // 18位身份证需要验证最后一位校验位
            if (data.length == 18) {
                data = data.split('')
                // ∑(ai×Wi)(mod 11)
                // 加权因子
                const factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
                // 校验位
                const parity = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2]
                let sum = 0
                let ai = 0
                let wi = 0
                for (let i = 0; i < 17; i++) {
                    ai = data[i]
                    wi = factor[i]
                    sum += ai * wi
                }
                const last = parity[sum % 11]
                if (parity[sum % 11] != data[17]) {
                    tip = '身份证号格式错误'
                    pass = false
                }
            }
        }
        return pass
    }

    /**
     * 手机号/座机号验证
     */
    function checkPhone() {
        const mobile = /^1[3|5|8]\d{9}$/, phone = /^0\d{2,3}-?\d{7,8}$/;
        return mobile.test(data) || phone.test(data);
    }

    /**
     * 姓名验证
     */
    function checkName() {
        //不能有特殊字符和数字
        //可以输入英文，可以有空格，可以输入英文名字中的点
        //可以输入汉字
        //中文英文不能同时出现90o
        //长度在1-20
        return /^([\u4e00-\u9fa5]{1,20}|[a-zA-Z\\.\\s]{1,20})$/.test(data)
    }

    /**
     * 邮箱验证
     */
    function checkEmail() {
        return /^([A-Za-z0-9_\-\.\u4e00-\u9fa5])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,8})$/.test(data)
    }

    if (type === 'empty') {
        error(emptyCheck())
    } else if (type === 'idCard') {
        error(checkIdCard())
    } else if (type === 'phone') {
        error(checkPhone())
    } else if (type === 'name') {
        error(checkName())
    } else if (type === 'boolean') {
        error(Boolean(data))
    } else if (type === 'email') {
        error(checkEmail())
    } else if (type === 'rule') {
        error(rule(data))
    }
}

export default {
    check,
}
